<template>
  <div>
    <el-dialog :title="title" :visible="visible" width="700px" @update:visible="updateVisible"
               :close-on-click-modal="false" @open="openDialog" @close="updateVisible(false)">
      <el-form :model="ruleForm" label-position="right" label-width="110px" ref="ruleForm" :rules="rules">
        <el-form-item label="字段关联" prop="isContact">
          <el-radio-group v-model="ruleForm.isContact" @change="changeClearValidate">
            <el-radio :label="0">不关联</el-radio>
            <el-radio :label="1">关联其他表字段</el-radio>
            <el-radio :label="2">关联当前表字段</el-radio>
            <el-radio :label="3">关联文件</el-radio>
          </el-radio-group>
        </el-form-item>
        <!--        不关联-->
        <el-form-item label="生成规则" v-if="!ruleForm.isContact" prop="ruleType">
          <el-cascader style="width: 100%"
                       v-model="ruleForm.ruleType"
                       :options=ruleOptions
                       filterable clearable
                       @change="changeCascader"
          >
            <template slot-scope="{ node, data }">
              <span>{{ data.label }}</span>
              <el-badge is-dot class="item" v-if="data.type">
              </el-badge>
            </template>
          </el-cascader>
        </el-form-item>
        <div v-if="!ruleForm.isContact && ruleForm.ruleType && ruleForm.ruleType.length === 3">
          <el-form-item v-for="(item,index) of params"
                        :key="index"
                        :label="item.label">
            <el-input v-model="item.name" type="textarea" :autosize="{ minRows: 4, maxRows: 8}"
                      :placeholder="`请输入${item.label}`"
                      v-if="ruleForm.ruleType[2].indexOf('String') !== -1"></el-input>
            <el-input-number v-model="item.name" :min="0" label="请输入参数要求的值"
                             v-if="ruleForm.ruleType[2].indexOf('int') !== -1"></el-input-number>
            <el-date-picker
              v-if="ruleForm.ruleType[2].indexOf('date') !== -1"
              type="date"
              v-model="item.name"
              value-format="yyyy-MM-dd"
              :placeholder="`请输入${item.label}`">
            </el-date-picker>
            <el-date-picker
              v-if="ruleForm.ruleType[2].indexOf('time') !== -1"
              type="datetime"
              v-model="item.name"
              value-format="yyyy-MM-dd HH:mm:ss"
              :placeholder="`请输入${item.label}`">
            </el-date-picker>
          </el-form-item>
          <el-form-item v-if="ruleForm.ruleType[1] === 'com.github.javafaker.service.FakeValuesService/regexify'">
            <el-button type="text" @click="dialogReList=true">选择已有的正则表达式</el-button>
          </el-form-item>
        </div>
        <!--        关联其他表字段-->
        <el-form-item label="表名" v-if="ruleForm.isContact === 1" prop="contactTable">
          <el-select v-model="ruleForm.contactTable" filterable placeholder="请选择关联的表"
                     @change="switchTable('contactTable')">
            <el-option
              v-for="item in tables"
              :key="item.TABLE_NAME || item.name"
              :label="item.TABLE_NAME || item.name"
              :value="item.TABLE_NAME || item.name">
            </el-option>
          </el-select>
          <span>&nbsp;&nbsp;&nbsp;共查询出<span style="color: #0044f0">&nbsp;{{ contactTableCount }}&nbsp;</span>条数据</span>
        </el-form-item>
        <el-form-item label="字段名" v-if="ruleForm.contactTable && ruleForm.isContact === 1 && contactTableCount > 0"
                      prop="contactColumn">
          <el-select v-model="ruleForm.contactColumn" filterable placeholder="请选择关联的字段"
                     @change="changeClearValidate('contactColumn')">
            <el-option
              v-for="item in columnOptions"
              :key="item.COLUMN_NAME"
              :label="item.COLUMN_NAME"
              :value="item.COLUMN_NAME">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="过滤条件" v-if="ruleForm.contactColumn && ruleForm.isContact === 1 && contactTableCount > 0">
          <div>
            <CommonEditor
              :value="ruleForm.sqlText"
              language="sql"
              @input="changeTextarea"
            ></CommonEditor>
          </div>
        </el-form-item>
        <!--        关联当前表字段-->
        <el-form-item label="当前表字段" v-if="ruleForm.isContact === 2"
                      prop="copyCurrentField">
          <el-select v-model="ruleForm.copyCurrentField" filterable placeholder="请选择关联的字段"
                     @change="changeClearValidate('copyCurrentField')">
            <el-option
              v-for="item in currentFields"
              :key="item.COLUMN_NAME"
              :label="item.COLUMN_NAME"
              :value="item.COLUMN_NAME"
              :disabled="item.disabled">
            </el-option>
          </el-select>
          <div style="color: #909399">当前配置字段的值与选择的当前表字段生成的值一致</div>
        </el-form-item>
        <el-form-item label="是否映射" prop="isMapping" v-if="ruleForm.copyCurrentField && ruleForm.isContact === 2">
          <el-radio-group v-model="ruleForm.isMapping" @change="changeClearValidate">
            <el-radio :label="0">否</el-radio>
            <el-radio :label="1">是</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="映射JSON" prop="mappingJson" v-if="ruleForm.isMapping && ruleForm.isContact === 2">
          <vue-json-editor
            v-model="ruleForm.mappingJson"
            :showBtns="false"
            :mode="'code'"
            @has-error="onError"
          />
          <!--          <b-code-editor v-model="ruleForm.mappingJson" :auto-format="true" :smart-indent="true" theme="idea"-->
          <!--                         :indent-unit="4" :line-wrap="false" ref="editor"></b-code-editor>-->
        </el-form-item>
        <el-form-item label="匹配的KEY" prop="matchKey" v-if="ruleForm.isMapping && ruleForm.isContact === 2"
                      style="width: 50%">
          <el-input v-model="ruleForm.matchKey" maxlength="20" show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="取值的KEY" prop="valueKey" v-if="ruleForm.isMapping && ruleForm.isContact === 2"
                      style="width: 50%">
          <el-input v-model="ruleForm.valueKey" maxlength="20" show-word-limit></el-input>
        </el-form-item>
        <!--        关联文件-->
        <el-form-item label="选择文件" prop="fileList" v-if="ruleForm.isContact === 3">
          <el-upload class="upload-demo" :file-list="ruleForm.fileList" :before-upload="beforeUpload"
                     :http-request="uploadFile"
                     accept=".xls, .xlsx"
                     :on-remove="removeFile" :on-exceed="handleExceed" drag action="" :limit="1" ref="upload">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            <div class="el-upload__tip" slot="tip">只能上传单个xls、xlsx文件，且不超过5M</div>
          </el-upload>
          <el-button type="text" style="display: inline-block" @click="downloadTemplate">下载模板</el-button>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="updateVisible(false)">取 消</el-button>
        <el-button type="primary" @click="testFaker(ruleForm.ruleType,ruleForm.defaultValue)">测试结果
        </el-button>
        <el-button type="primary" @click="determineConfig('ruleForm')">保 存</el-button>
      </div>
    </el-dialog>
    <ReList :visible.sync="dialogReList" @reValue="getReValue" @againRefreshReConfig="againRefreshReConfig"></ReList>
  </div>
</template>

<script>
import {
  getFieldByTableNameApi,
  getCountByTableNameApi,
  testFakerApi
} from '@/api/api'
import ReList from "./reList"
import CommonEditor from '@/components/CommonEditor/index'
// import sqlFormatter from 'sql-formatter'
import {deepClone} from '@/utils/util'
import vueJsonEditor from 'vue-json-editor'

export default {
  name: "ruleForm",
  props: ["visible", "tables", "dbInfo", "table", 'row', 'ruleOptions'],
  components: {ReList, CommonEditor, vueJsonEditor},
  data() {
    var checkUpload = (rule, value, callback) => {
      if (value === undefined || this.ruleForm.fileList === []) {
        callback(new Error('请上传文件'));
      } else {
        callback();
      }
    };
    return {
      params: [{name: ""}],
      columnOptions: [],
      ruleForm: {
        isContact: 0,
        columnName: "",
        defaultValue: "",
        ruleType: [],
        contactTable: "",
        contactColumn: "",
        sqlText: "",
        copyCurrentField: "",
        isMapping: 0,
        mappingJson: undefined,
        matchKey: "",
        valueKey: "",
        fileName: "",
        fileList: [],
        filePath: ""
      },
      rules: {
        defaultValue: [
          {required: true, message: '请输入参数值', trigger: 'blur'}
        ],
        ruleType: [
          {required: true, message: '请选择生成规则', trigger: 'change'}
        ],
        isContact: [
          {required: true, message: '请确定字段关联选项', trigger: 'change'}
        ],
        contactTable: [
          {required: true, message: '请先选择关联其他表', trigger: 'blur'}
        ],
        contactColumn: [
          {required: true, message: '请先选择关联其他表字段', trigger: 'blur'}
        ],
        copyCurrentField: [
          {required: true, message: '请选择当前表字段', trigger: 'blur'}
        ],
        mappingJson: [
          {required: true, message: '请输入映射JSON', trigger: 'blur'}
        ],
        matchKey: [
          {required: true, message: '请输入匹配的KEY', trigger: 'blur'}
        ],
        valueKey: [
          {required: true, message: '请输入取值的KEY', trigger: 'blur'}
        ],
        fileList: [
          {required: true, validator: checkUpload, message: '上传文件不能为空', trigger: 'blur'}
        ]
      },
      dialogReList: false,
      title: "",
      currentFields: [],
      contactTableCount: 0
    }
  },
  methods: {
    downloadTemplate() {
      this.api({
        url: "/downloadTemplate",
        method: "post",
        responseType: 'blob',
        data: {
          "fileName": "关联文件模板",
          "sheetName": "关联文件模板",
          "headerName": "字段名"
        }
      }).then(resp => {
        const link = document.createElement('a');
        let blob = new Blob([resp.data], {type: 'application/vnd.ms-excel'});
        link.style.display = 'none';
        link.href = URL.createObjectURL(blob);
        link.setAttribute('download', decodeURI(resp.headers["filename"]));
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        this.$message({message: "下载模板成功", type: 'success'})
      });
    },
    changeCascader() {
      let arr = []
      this.params = []
      if (this.ruleForm.ruleType && this.ruleForm.ruleType.length === 3) {
        this.api({
          url: "/ruleConfig/getParams",
          method: "get",
          params: {value: this.ruleForm.ruleType[1], child_value: this.ruleForm.ruleType[2]}
        }).then(resp => {
          for (let i = 0; i < this.ruleForm.ruleType[2].split(",").length; i++) {
            arr.push({
              name: "",
              label: resp.split(",")[i]
            })
          }
          this.params = arr;
        });
        // this.params = new Array(this.ruleForm.ruleType[2].split(",").length).fill({name:""})
      }
    },
    onError(value) {
    },
    changeClearValidate(value) {
      if (value) {
        this.$refs["ruleForm"].clearValidate(value);
      } else {
        this.$refs["ruleForm"].clearValidate();
      }
    },
    changeTextarea(val) {
      this.ruleForm.sqlText = val
    },

    /*更新本组件弹框状态*/
    updateVisible(val) {
      // this.$refs.ruleForm.resetFields()
      this.$emit('update:visible', val)
    },

    /*切换表select。获取列options*/
    async switchTable(value) {
      let copyDbInfo
      copyDbInfo = {...this.dbInfo}
      copyDbInfo["tableName"] = this.ruleForm.contactTable
      let resp = await getFieldByTableNameApi(copyDbInfo)
      let resp1 = await getCountByTableNameApi(copyDbInfo)
      this.columnOptions = resp
      this.contactTableCount = resp1[0]["count(*)"] !== undefined ? resp1[0]["count(*)"] : resp1[0]["count()"]
      this.changeClearValidate(value)
    },
    /*打开行配置规则表单对话框*/
    openDialog() {
      console.log(this.row)
      let list = deepClone(this.table, [])
      this.contactTableCount = 0
      this.ruleForm = {
        contactTable: this.row.contactTable,
        contactColumn: this.row.contactColumn,
        sqlText: this.row.sqlText,
        isContact: !this.row.isContact ? 0 : this.row.isContact,
        ruleType: this.row.FAKER,
        defaultValue: this.row.VALUE,
        columnName: this.row.COLUMN_NAME,
        copyCurrentField: this.row.copyCurrentField,
        isMapping: this.row.isMapping,
        mappingJson: this.row.mappingJson,
        matchKey: this.row.matchKey,
        valueKey: this.row.valueKey,
        filePath: this.row.filePath,
        fileName: this.row.fileName,
        fileList: this.row.fileList,
      }
      this.params = this.row.params
      if (this.row.isContact === 1) {
        this.switchTable('contactTable')
      } else if (this.row.isContact === 3 && !this.ruleForm.fileList[0]["name"]) {
        this.ruleForm.fileList[0]["name"] = this.row.fileName
      }
      this.title = "配置 " + this.row.COLUMN_NAME + " 字段规则"
      this.currentFields = list.map(item => {
        if (item.COLUMN_NAME === this.ruleForm.columnName) {
          item["disabled"] = true
        }
        return item
      })
      this.$nextTick(() => {
        this.$refs["ruleForm"].clearValidate();
      });

    },

    /*表单默认值用re的值填充*/
    getReValue(value) {
      this.params[0].name = value
    },

    /*更新父组件Re配置结果*/
    againRefreshReConfig() {
      this.$emit("againRefreshReConfig", "")
    },

    /*确定提交配置规则表单*/
    determineConfig(ruleForm) {
      let params = {}
      let showDialog = true
      this.$refs[ruleForm].validate(valid => {
        if (valid) {
          if (this.ruleForm.isContact === 1) {
            params = {
              contactTable: this.ruleForm.contactTable,
              contactColumn: this.ruleForm.contactColumn,
              sqlText: this.ruleForm.sqlText = this.ruleForm.sqlText === undefined
              || this.ruleForm.sqlText === null ? "" : this.ruleForm.sqlText,
            }
          } else if (this.ruleForm.isContact === 0) {
            if (this.ruleForm.ruleType && this.ruleForm.ruleType.length === 3) {
              this.params.forEach(item => {
                if (!item.name && item.name !== 0) {
                  this.$message.error(item.label + "不能为空")
                  showDialog = false
                }
              })
            }
            params = {
              ruleType: this.ruleForm.ruleType,
              defaultValue: this.params.map(item => item.name).join(","),
              params: this.params
            }
          } else if (this.ruleForm.isContact === 2) {
            params = {
              copyCurrentField: this.ruleForm.copyCurrentField,
              isMapping: this.ruleForm.isMapping,
              mappingJson: this.ruleForm.mappingJson,
              matchKey: this.ruleForm.matchKey,
              valueKey: this.ruleForm.valueKey
            }
          } else {
            params = {
              fileList: this.ruleForm.fileList,
              filePath: this.ruleForm.filePath,
              fileName: this.ruleForm.fileName
            }
          }
          params["isContact"] = this.ruleForm.isContact
          params["columnName"] = this.ruleForm.columnName
          if (showDialog) {
            this.updateVisible(false)
            this.$emit('updateRefreshKey', params)
          }
        }
      })
    },

    /*测试随机数*/
    async testFaker(FAKER, VALUE) {
      //关联的情况
      let params = {}
      let showDialog = true
      this.$refs["ruleForm"].validate(async valid => {
        if (valid) {
          if (this.ruleForm.isContact === 1) {
            params = {
              contactTable: this.ruleForm.contactTable,
              contactColumn: this.ruleForm.contactColumn,
              sqlText: this.ruleForm.sqlText = this.ruleForm.sqlText === undefined || this.ruleForm.sqlText === null ? "" : this.ruleForm.sqlText,
              contactTableCount: this.contactTableCount,
              dbInfo: this.dbInfo,
            }
          } else if (this.ruleForm.isContact === 3) {
            params = {
              filePath: this.ruleForm.filePath,
              COLUMN_NAME: this.row.COLUMN_NAME
            }
          } else if (this.ruleForm.isContact === 2) {
            params = {
              copyCurrentField: this.ruleForm.copyCurrentField,
              isMapping: this.ruleForm.isMapping,
              mappingJson: this.ruleForm.mappingJson,
              matchKey: this.ruleForm.matchKey,
              valueKey: this.ruleForm.valueKey
            }
          }
          //不关联的情况
          else {
            if (this.ruleForm.ruleType && this.ruleForm.ruleType.length === 3) {
              this.params.forEach(item => {
                if (!item.name && item.name !== 0) {
                  this.$message.error(item.label + "不能为空")
                  showDialog = false
                  return
                }
              })
            }
            VALUE = this.params.map(item => item.name).join(",")
            params = {
              packageName: FAKER && FAKER.length > 1 ? FAKER[1].split("/")[0] : "",
              methodName: FAKER && FAKER.length > 1 ? FAKER[1].split("/")[1] : "",
              params: FAKER && FAKER.length > 2 ? FAKER[2] : "",
              value: VALUE ? VALUE : ""
              // value: VALUE ? VALUE.indexOf("】") !== -1 ? VALUE.split("】")[1] : VALUE : ""
            }
          }
          params["isContact"] = this.ruleForm.isContact
          if (showDialog) {
            let resp = await testFakerApi(params)
            if (resp.code !== "500") {
              this.$notify({title: "随机数", message: typeof resp + " : " + resp, position: 'top-left'})
            }
          }
        }

      })
    },

    // 上传前判断格式和大小
    beforeUpload(file) {
      let FileExt = file.name.replace(/.+\./, "");
      if (['xls', 'xlsx'].indexOf(FileExt.toLowerCase()) === -1) {
        this.$message({
          type: 'warning',
          message: '请上传后缀名为xls、xlsx的附件！'
        });
        return false;
      }
      if (file.size > 5 * 1024 * 1024) {
        this.$message.warning('文件大小超过5M 无法上传');
        return false;
      }
      return true;
    },

    handleExceed() {
      this.$message.warning('一次最多只能上传一个文件');
    },

    uploadFile(option) {
      let FormDatas = new FormData()
      FormDatas.append('file', option.file);
      this.ruleForm.fileList = []
      this.ruleForm.fileList.push(option.file);
      this.ruleForm.fileName = option.file.name;
      this.$refs.ruleForm.validateField('fileList');
      this.api({
        url: "/uploadCheck/" + this.row.COLUMN_NAME,
        method: "post",
        data: FormDatas,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then(resp => {
        console.log(this.ruleForm.fileList)
        if (resp.code === "500") {
          this.ruleForm.fileList = [];
        } else {
          this.ruleForm.filePath = resp
        }
      });
      this.changeClearValidate("fileList")
    },

    removeFile() {
      this.ruleForm.fileList = [];
    }
  }
}
</script>

<style lang="scss">
.jsoneditor {
  border: 1px solid #dcdfe6 !important;
}

.jsoneditor-menu {
  display: none;
}

#cm-complete-0 {
  z-index: 9999;
}
</style>
